package com.lpf;

import net.bytebuddy.implementation.bind.annotation.*;

import java.lang.reflect.Method;
import java.util.concurrent.Callable;

/**
 * Byte Buddy 提供了一些预定义的注解，通过这些注解可以告诉 Byte Buddy 将哪些需要的数据注入到 Interceptor 中。
 */
public class Interceptor02 {

    /**
     * @param obj          目标对象
     * @param allArguments 注入目标方法的全部参数
     * @param zuper        调用目标方法，必不可少
     * @param method       目标方法
     * @param db           目标对象
     * @return
     * @throws Exception
     */
    @RuntimeType // 告诉 Byte Buddy 不要进行严格的参数类型检测，在参数匹配失败时，尝试使用类型转换方式（runtime type casting）进行类型转换，匹配相应方法。
    public Object intercept(@This Object obj, // 注入被拦截的目标对象（即前面的 DB 对象）
                            @AllArguments Object[] allArguments, // 注入目标方法的全部参数
                            @SuperCall Callable<?> zuper, // 用来调用目标方法
                            @Origin Method method, // 注入目标方法对应的 Method 对象
                            @Super DB db) throws Exception { // 注入目标对象，通过该对象可以调用目标对象的所有方法

        // 从下面两行输出可以看出，obj和db是一个对象
        System.out.println(obj);
        System.out.println(db);

        return zuper.call(); // 调用目标方法
    }
}
